<?php
declare (strict_types=1);

namespace app\admin\logic\user;

use app\admin\model\user\Permission as PermissionModel;
use app\common\exception\LogicException;

class Permission extends PermissionModel
{
    /**
     * 创建节点
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-03-19
     *
     * @param array $permission [description]
     * @return   [type]                                [description]
     */
    public function createPermission(array $permission): self
    {
        // 验证数据
        $this->getValidate()->scene('create')->failException()->check($permission);
        // 用户信息
        $re = $this->save($permission);
        // 创建成功
        if (!$re) {
            throw new LogicException('创建失败');
        }

        return $this;
    }

    /**
     * 编辑节点
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-03-19
     *
     * @param array $permission [description]
     * @return   [type]                               [description]
     */
    public function editPermission(array $data)
    {
        // 验证数据
        $this->getValidate()->scene('edit')->failException()->check($data);
        // 用户信息
        $permission             = $this->where('id', $data['id'])->findOrFail();
        $permission->title      = $data['title'];
        $permission->permission = $data['permission'];
        $permission->remark     = $data['remark'];
        $permission->is_menu    = $data['is_menu'];

        if (!$permission->save()) {
            throw new LogicException('编辑失败');
        }

        return $permission;
    }

    /**
     * 删除节点
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-03-19
     *
     * @param int $id [description]
     * @return   [type]                             [description]
     */
    public function deletePermission(int $id): void
    {
        $permission = $this->where('id', $id)->findOrFail();

        // 是否有子级
        if ($this->hasChildren($permission->id)) {
            throw new LogicException('存在子节点，不可删除');
        }

        if (!$permission->delete()) {
            throw new LogicException('删除失败');
        }
    }

    /**
     * 获取列表
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-03-19
     *
     * @param integer $pid 父级ID
     * @return   [type]                              [description]
     */
    public function getList($pid = 0)
    {
        $list = $this->where('pid', $pid)->order('sort')->select();
        if ($list) {
            foreach ($list as $permission) {
                $permission->hasChildren = $this->hasChildren($permission->id) ? 1 : 0;
            }
        }

        return $list;
    }

    /**
     * 是否有子节点
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-03-19
     *
     * @param int|integer|array $pid [description]
     * @return   boolean                             [description]
     */
    public function hasChildren($pid = 0): bool
    {
        if (is_array($pid)) {
            return $this->whereIn('pid', $pid)->find() ? true : false;
        }

        return $this->where('pid', $pid)->find() ? true : false;
    }

    /**
     * 获取树形列表
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-03-19
     *
     * @param integer $pid 父级ID
     * @return   [type]                              [description]
     */
    public function getTreeList($pid = 0, $level = 0)
    {
        $list = [];
        static $ids;
        if (!$ids) {
            $ids = app(Group::class)->getCurrentLoginRuleList();
        }
        $data = $this->where('pid', $pid)->whereIn('id', $ids)->where('status', 1)->order('sort')->select();
        if ($data) {
            ++$level;
            // 是否浮动
            $float = null;
            foreach ($data as $permission) {
                if (is_null($float)) {
                    $float = $this->hasChildren($data->column('id')) ? 1 : 0;
                }
                $item   = [
                    'id'       => $permission->id,
                    'title'    => $permission->title,
                    'level'    => $level,
                    'float'    => $float,
                    'children' => $this->getTreeList($permission->id, $level),
                ];
                $list[] = $item;
            }
        }

        return $list;
    }

}
